/********************************Copyright (c)**********************************\
**
**                   (c) Copyright 2019, Main, China, QD.
**                           All Rights Reserved
**
**                                 By(wo4fisher)
**                           http://www.wo4fisher.com
\********************************End of Head************************************/
#include "timer_a.h"
#include "led.h"
#include "watchdog.h"
#include "lcd.h"

static const uint16_t TIMER_A_getTACCRCTLxAddress[] = {
    0x0000,
    0x0162,
    0x0164,
    0x0166};

static const uint16_t TIMER_A_getTACCRxAddress[] = {
    0x0000,
    0x0172,
    0x0174,
    0x0176};

void TIMER_A_start_Counter(uint16_t TIMER_A_x_MODE)
{
    TACTL = (TACTL & (0xffcf)) + TIMER_A_x_MODE;
}

void Timer_A_stop(void)
{
    TACTL &= 0xffcf;
}

void Timer_A_initAsContinuousMode(Timer_A_initAsContinuousModeTypedef Timer_A_initAsContinuousModeParam)
{
    uint16_t newTACTL = (TACTL & 0xfc09) +
                        Timer_A_initAsContinuousModeParam.clockSource +
                        Timer_A_initAsContinuousModeParam.clockSourceDivider +
                        Timer_A_initAsContinuousModeParam.timerClear +
                        Timer_A_initAsContinuousModeParam.timerInterruptEnable;
    if (Timer_A_initAsContinuousModeParam.timerStart == TIMER_A_START)
    {
        newTACTL |= TIMER_A_CONTINUOUS_MODE;
    }
    TACTL = newTACTL;
}

void Timer_A_initAsUpMode(Timer_A_initAsUpModeTypedef Timer_A_initAsUpModeParam)
{
    uint16_t newTACTL = (TACTL & 0xfc09) +
                        Timer_A_initAsUpModeParam.clockSource +
                        Timer_A_initAsUpModeParam.clockSourceDivider +
                        Timer_A_initAsUpModeParam.timerClear +
                        Timer_A_initAsUpModeParam.timerInterruptEnable;
    if (Timer_A_initAsUpModeParam.timerStart == TIMER_A_START)
    {
        newTACTL |= TIMER_A_UP_MODE;
    }
    TACCR0 = Timer_A_initAsUpModeParam.timerPeriod;
    TACCTL0 = Timer_A_initAsUpModeParam.captureCompareInterruptEnable0;
    TACTL = newTACTL;
}

void Timer_A_clear(void)
{
    TACTL |= TACLR;
}

void Timer_A_enableInterrupt(void)
{
    TACTL |= TAIE;
}

void Timer_A_disableInterrupt(void)
{
    TACTL &= ~TAIE;
}

uint32_t Timer_A_getInterruptStatus(void)
{
    return (TACTL & TAIFG);
}

void Timer_A_clearTimerInterrupt(void)
{
    TACTL &= ~TAIFG;
}

/*********** user api *************/
//******************************************************************************
//
// This is the Timer A0 interrupt vector service routine.
//
//******************************************************************************

#define TIMER_PERIOD 4096 // 8 times 1 second
#define TIMER_IRQ_CNT_ADC 480
#define TIMER_IRQ_CNT_MOTOR 8
#define TIMER_IRQ_CNT_LED 50
#define TIMER_IRQ_CNT_SPRAY 100
#define TIMER_IRQ_CNT_1S 8

uint32_t timer_cnt = 0;
__IO TIMER_FLAG_T timer_irq_flag_t;

#if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
#pragma vector = TIMERA0_VECTOR
__interrupt
#elif defined(__GNUC__)
__attribute__((interrupt(TIMERA0_VECTOR)))
#endif
    void
    TIMERA0_ISR(void)
{
    switch (TAIV)
    {
    case 0x02:
        break;
    case 0x04:
        break;
    case 0x0A:
        CLR_WDT();
        timer_cnt++;
        if(timer_cnt % TIMER_IRQ_CNT_1S == 0)
        {
            LPM3_EXIT;
        }
        if (timer_cnt % TIMER_IRQ_CNT_ADC == 0)
        {
            timer_irq_flag_t.timer_flag_adc = true;
            LPM3_EXIT;
        }        
    }
    TACCR0 = TIMER_PERIOD;
    Timer_A_clearTimerInterrupt();
}

void Timer_A_init(void)
{
    Timer_A_clear();
    Timer_A_clearTimerInterrupt();
    Timer_A_initAsUpModeTypedef param = {0};
    param.clockSource = TIMER_A_SOURCE_ACLK; // 32.768khz;
    param.clockSourceDivider = TIMER_A_DIVIDER_1;
    param.timerPeriod = TIMER_PERIOD;                                    // TBSSEL_2 + MC_2
    param.timerInterruptEnable = TIMER_A_ENABLE_INTERRUPT;               // TIMER_A_ENABLE_INTERRUPT;
    param.captureCompareInterruptEnable0 = TIMER_A_CCR_ENABLE_INTERRUPT; // 0;
    param.timerClear = TIMER_A_CLEAR;
    param.timerStart = TIMER_A_START;
    Timer_A_initAsUpMode(param);
}

/**********  end of file *******/
